var createError = require("http-errors");
var express = require("express"); //生成一个express实例 app。
var path = require("path");
var cookieParser = require("cookie-parser");

var logger = require("morgan");
var settings = require("./settings.ts");
var flash = require("connect-flash");

var session = require("express-session");
var MongoStore = require("connect-mongo")(session);
var setApis = require("./src/rests/index.ts");
// 导入路由模块
var indexRouter = require("./routes/index.ts");
var usersRouter = require("./routes/users.ts");
var constJson = require("./config/const.json");

var app = express();

// view engine setup
app.set("views", path.join(__dirname, "views/ejs")); //设置 views 文件夹为存放视图文件的目录, 即存放模板文件的地方,__dirname 为全局变量,存储当前正在执行的脚本所在的目录。
// app.set('view engine', 'jade'); //默认是jade。
app.set("view engine", "ejs"); //设置视图模板引擎为 ejs

app.use(
  session({
    name: settings.cookieName, //返回客户端的 key 的名称，默认为 connect.sid,也可以自己设置。
    secret: settings.cookieSecret, // 一个 String 类型的字符串，作为服务器端生成 session 的签名。
    cookie: {
      maxAge: 1000 * 60 * 60 * 24,
      httpOnly: false,
    }, //设置返回到前端 key 的属性，默认值为{ path: ‘/’, httpOnly: true, secure: false, maxAge: null }。
    resave: false, //强制保存 session 即使它并没有变化,。默认为 true。建议设置成 false。 don't save session if unmodified
    saveUninitialized: true, //强制将未初始化的 session 存储。当新建了一个 session 且未设定属性或值时，它就处于未初始化状态。在设定一个 cookie 前，这对于登陆验证，减轻服务端存储压力，权限控制是有帮助的。(默 认:true)。建议手动添加。
    rolling: true, //在每次请求时强行设置 cookie，这将重置 cookie 过期时间(默认:false)
    store: new MongoStore({
      url:
        "mongodb://" + settings.host + ":" + settings.port + "/" + settings.db,
      touchAfter: 24 * 3600,
    }),
  })
);

app.use(flash()); //flash 是一个在 session 中用于存储信息的特定区域。信息写入 flash ，下一次显示完毕后即被清除。典型的应用是结合重定向的功能，确保信息是提供给下一个被渲染的页面。

app.use(logger("dev")); //加载日志中间件。

// 启动服务器
app.listen(8100, () => {
  console.log("express server running at http://127.0.0.1");
});

app.use(cookieParser()); //加载解析cookie的中间件。
setApis(app); //设置接口信息。
app.use(express.static(path.join(__dirname, "public"))); //设置public文件夹为存放静态文件的目录。
app.use(express.static(path.join(__dirname, "views"))); //设置public文件夹为存放静态文件的目录
app.use(express.static(path.join(__dirname, "node_modules"))); //设置public文件夹为存放静态文件的目录
app.use(express.static(path.join(constJson.root, constJson.directory))); //设置public文件夹为存放静态文件的目录
// 把路由模块，注册到 app 上

app.use("/users", usersRouter); //路由控制器。
app.use("/", indexRouter); //路由控制器。

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
}); //捕获404错误，并转发到错误处理器

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get("env") === "development" ? err : {}; //开发环境下的错误处理器，将错误信息渲染error模版并显示到浏览器中

  // render the error page
  res.status(err.status || 500);
  res.render("error");
  //生产环境下的错误处理器，将错误信息渲染error模版并显示到浏览器中。
});

module.exports = app; //导出app实例供其他模块调用
